﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Threading.Tasks;
using Casamiel.API.Application;
using Casamiel.API.Application.Services;
using Casamiel.Application;
using Casamiel.Common;
//using Microsoft.AspNetCore.Http.Internal;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using NLog;
//using Casamiel.Domain.AggregatesModel;
using PaySharp.Core;
using PaySharp.Wechatpay;
using PaySharp.Wechatpay.Response;

namespace Casamiel.API.Controllers
{
    /// <summary>
    /// 微信小程序支付
    /// </summary>
    /// 
    //[Route("MiniAppPayNotify")]
    [ApiVersionNeutral]
    public class MiniAppPayNotifyController : Controller
    {
        /// <summary>
        /// 
        /// </summary>
        private readonly IPaymentService paymentService;
        private readonly IIcApiService _iicApiService;
        private readonly IUserLogService _userLogService;
        private readonly NLog.ILogger logger = LogManager.GetLogger("PayService");
        private readonly WxPaySettigs _wxPay;
        private readonly List<MiniAppSettings> _listminiAppSettings;
        private readonly ICasaMielSession _session;
        private readonly IStoreService _storeService;
        private readonly IStoreApiService _storeApiService;
        private readonly IAllPayService payService;
        private IGateways _gateways;
        /// <summary>
        /// Initializes a new instance of the <see cref="T:Casamiel.API.Controllers.MiniAppPayNotifyController"/> class.
        /// </summary>
        /// <param name="paymentRecord">Payment record.</param>
        /// <param name="userLog">User log.</param>
        /// <param name="payService">Pay service.</param>
        /// <param name="iicApiService">Iic API service.</param>
        /// <param name="optionsSnapshot">Options snapshot.</param>
        /// <param name="wxAppSettings">Wx app settings.</param>
        /// <param name="session">Session.</param>
        /// <param name="storeService">Store service.</param>
        /// <param name="storeApiService">Store API service.</param>
        public MiniAppPayNotifyController(IPaymentService paymentRecord,
                                          IUserLogService userLog, IAllPayService payService,
            IIcApiService iicApiService, IOptionsSnapshot<WxPaySettigs> optionsSnapshot, IOptionsSnapshot<List<MiniAppSettings>> wxAppSettings, ICasaMielSession session,
                                          IStoreService storeService, IStoreApiService storeApiService)
        {
            if (optionsSnapshot == null) {
                throw new ArgumentNullException(nameof(optionsSnapshot));
            }

            if (wxAppSettings == null) {
                throw new ArgumentNullException(nameof(wxAppSettings));
            }

            paymentService = paymentRecord;
            _userLogService = userLog;
            _iicApiService = iicApiService;
            _wxPay = optionsSnapshot.Value;
            _listminiAppSettings = wxAppSettings.Value;
            _session = session;
            _storeService = storeService;
            _storeApiService = storeApiService;
            this.payService = payService;
        }
        /// <summary>
        /// 支付成功服务器回调
        /// </summary>
        /// <returns></returns>
        /// 
        //[HttpGet]
        //[HttpPost]

        public async Task Index()
        {
           // Request.EnableRewind();

            string appid = "";
            var query = Request.QueryString;
            if (query.HasValue) {
                appid = query.Value.TrimStart('?');
                Console.WriteLine(appid);
            }
            var _miniAppSettings = _listminiAppSettings.Find(c => c.appid == appid);
            if (_miniAppSettings == null) {
                _miniAppSettings = _listminiAppSettings[0];
            }
            var wechatpayMerchant = new Merchant {
                AppId = _miniAppSettings.appid,
                MchId = _miniAppSettings.MchId,
                Key = _miniAppSettings.Key,
                AppSecret = _miniAppSettings.AppSecret,
                SslCertPath = _miniAppSettings.SslCertPath,
                SslCertPassword = _miniAppSettings.SslCertPassword,
                NotifyUrl = _miniAppSettings.NotifyUrl,
            };
            //if(!string.IsNullOrEmpty(appid)){

            //    wechatpayMerchant.AppId = appid;
            //}
            WechatpayGateway ga = new WechatpayGateway(wechatpayMerchant);
            var gate = new Gateways();
            gate.Add(ga);
            _gateways = gate;
            Notify notify = new Notify(_gateways);
            notify.PaySucceed += Notify_PaySucceed;
            notify.RefundSucceed += Notify_RefundSucceed;
            notify.CancelSucceed += Notify_CancelSucceed;
            notify.UnknownNotify += Notify_UnknownNotify;
            notify.UnknownGateway += Notify_UnknownGateway;
            // 接收并处理支付通知
            await notify.ReceivedAsync().ConfigureAwait(false);
        }
        private bool Notify_UnknownNotify(object sender, UnKnownNotifyEventArgs e)
        {
            logger.Error("Notify_PaymentFailed:" + JsonConvert.SerializeObject(e));
            // 未知时的处理代码
            return false;
        }
        private void Notify_UnknownGateway(object arg1, UnknownGatewayEventArgs e)
        {
            logger.Error("Notify_UnknownGateway:" + JsonConvert.SerializeObject(e));
        }
        private bool Notify_RefundSucceed(object arg1, RefundSucceedEventArgs arg2)
        {
            // 订单退款时的处理代码
            logger.Trace($"RefundSucceed:{JsonConvert.SerializeObject(arg2)}");
            return true;
        }
        private bool Notify_CancelSucceed(object arg1, CancelSucceedEventArgs arg2)
        {
            // 订单撤销时的处理代码
            return true;
        }
        //private void Notify_PaymentFailed(object arg1, PayFailedEventArgs e)
        //{
        //    //throw new NotImplementedException();
        //    logger.Error("Notify_PaymentFailed:" + JsonConvert.SerializeObject(e));
        //}

        private bool Notify_PaySucceed(object arg1, PaySucceedEventArgs e)
        {
            // 支付成功时时的处理代码
            /* 建议添加以下校验。
             * 1、需要验证该通知数据中的OutTradeNo是否为商户系统中创建的订单号，
             * 2、判断Amount是否确实为该订单的实际金额（即商户订单创建时的金额），
             */
            if (e.GatewayType == typeof(WechatpayGateway)) {
                var wechatpayNotify = (NotifyResponse)e.NotifyResponse;
                Console.WriteLine($"OutTradeNo：{wechatpayNotify.OutTradeNo},TradeNo：{wechatpayNotify.TradeNo},{wechatpayNotify.TotalAmount / 100},{wechatpayNotify.MchId},{DateTime.Now.ToString("yyyyMMdd HH:mm:ss.fff", CultureInfo.CurrentCulture)}");

                logger.Trace($"OutTradeNo：{wechatpayNotify.OutTradeNo},TradeNo：{wechatpayNotify.TradeNo},{wechatpayNotify.TotalAmount / 100},{wechatpayNotify.MchId},{DateTime.Now.ToString("yyyyMMdd HH:mm:ss.fff", CultureInfo.CurrentCulture)}");
                var ss = payService.PayComplete(wechatpayNotify.OutTradeNo, wechatpayNotify.TradeNo, wechatpayNotify.TotalAmount / 100, wechatpayNotify.MchId);
                ss.Wait();
                return ss.GetAwaiter().GetResult();

                //同步通知，即浏览器跳转返回
            }
            //处理成功返回true
            return true;
        }
    }
}